package com.ak.ty.utils;


import com.alibaba.fastjson.JSON;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WjxUtils {

    public static String USER_AGENT = "User-Agent";
    public static String USER_AGENT_VALUE = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0";

    public static String js = "function dataenc(a,ktimes) {\n" +
            "    let c, d, e, b = ktimes % 10;\n" +
            "    for (0 == b && (b = 1),\n" +
            "             c = [],\n" +
            "             d = 0; d < a.length; d++)\n" +
            "        e = a.charCodeAt(d) ^ b,\n" +
            "            c.push(String.fromCharCode(e));\n" +
            "    return c.join(\"\")\n" +
            "}";

    /**
     * 普通的get请求
     *
     * @param url
     * @return
     */
    public static Connection.Response getUrl(String url) {
        Connection con = Jsoup.connect(url);
        con.header(USER_AGENT, USER_AGENT_VALUE)
                .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
                .header("Accept-Encoding", "gzip, deflate, sdch")
                .header("Content-Type", "text/html; charset=utf-8");
        try {
            return con.ignoreContentType(true).
                    followRedirects(true).
                    method(Connection.Method.POST).
                    execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getJqpram(String rn, String startTime, Integer activityId) {
        //脚本的执行结果
        String scriptResult = "";
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");//1.得到脚本引擎
        try {
            //2.引擎读取 脚本字符串
//            engine.eval(new StringReader(js));
            //如果js存在文件里，举例
            Resource aesJs = new ClassPathResource("static/js/cktoole_analysis.js");
            engine.eval(new FileReader(aesJs.getFile()));
            //3.将引擎转换为Invocable，这样才可以掉用js的方法
            Invocable invocable = (Invocable) engine;
            //4.使用 invocable.invokeFunction掉用js脚本里的方法，第一個参数为方法名，后面的参数为被调用的js方法的入参
            scriptResult = (String) invocable.invokeFunction("get_jqParam", rn, startTime, activityId);
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return scriptResult;
    }


    public static Integer getKtimes() {
//        return new Random().nextInt(280) + 50;
        int[] te = {321, 131, 176,126};
        return te[new Random().nextInt(te.length)];
    }

    public static String getCurId(String url) {
        String regEx = "[^0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(url);
        return m.replaceAll("").trim();
    }

    public static String dataenc(String jqnonce, Integer ktimes) {

        int b = ktimes % 10;
        StringBuilder c = new StringBuilder();
        int d = 0;
        if (b == 0) {
            b = 1;
        }
        for (; d < jqnonce.length(); d++) {
            int e = charCodeAt(jqnonce, d) ^ b;
            c.append(fromCharCode(e));
        }
        return c.toString();
    }

    public static Integer charCodeAt(String str, int i) {
        return (int) str.charAt(i);
    }

    public static String fromCharCode(int i) {
        return "" + (char) i;
    }

    public static String encodeURIComponent(String url) {
        // 对URL进行编码
        try {
            return URLEncoder.encode(url, "UTF-8")
                    .replaceAll("\\+", "%20")
                    .replaceAll("\\!", "%21")
                    .replaceAll("\\'", "%27")
                    .replaceAll("\\(", "%28")
                    .replaceAll("\\)", "%29")
                    .replaceAll("\\~", "%7E");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String buildMap(Map<String, String> map) {
        StringBuilder sb = new StringBuilder();
        int i = 0;
        int last = map.size();
        if (map.size() > 0) {
            sb.append("?");
            for (String key : map.keySet()) {
                sb.append(key).append("=");
                if (!StringUtils.isEmpty(map.get(key))) {
                    String value = map.get(key);
                    try {
                        value = URLEncoder.encode(value,"UTF-8");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    sb.append(value);
                }
                if (i != last - 1) {
                    sb.append("&");
                }
                i++;
            }
        }
        return sb.toString();
    }


    /**
     * 使用问卷星破解
     *
     * @param url
     * @param data
     * @return
     */
    public static boolean wjx(String url, String data) {
        try {
            Connection con = Jsoup.connect(url);
            String curId = getCurId(url);
            System.out.println(curId);

            con.header(USER_AGENT, USER_AGENT_VALUE)
                    .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
                    .header("Accept-Encoding", "gzip, deflate, sdch")
                    .header("Content-Type", "text/html; charset=utf-8");

            Connection.Response res = con.ignoreContentType(true).
                    followRedirects(true).
                    method(Connection.Method.GET).
                    execute();

            Map<String, String> datas = new HashMap<>();
            String temp = res.body();
//            System.out.println(temp);
            datas.put("curID", curId);
            datas.put("isMtitle", "0");
            datas.put("submittype", "1");

            datas.put("jpm", "19");
            datas.put("hlv", "1");
//            Integer[2] tt =[321, 176];

            int ktimes = getKtimes();
            datas.put("ktimes", String.valueOf(ktimes));

            String rndnum = temp.split("rndnum=\"")[1].split("var simple")[0].replaceAll("\";", "").trim();
            System.out.println("rndnum--" + rndnum);
            String starttime = temp.split("starttime=\"")[1].split("langVer=")[0].replaceAll("\";", "").trim();
            System.out.println("starttime--" + starttime);
            String jqnonce = temp.split("jqnonce=\"")[1].split("var isChuangGuan")[0].replaceAll("\";", "").trim();
            System.out.println("jqnoce--" + jqnonce);
//            String activityId = temp.split("var activityId =")[1].split("activityId=")[0].replaceAll(";", "").trim();


            //根据时间戳，生成的时间
            datas.put("starttime", starttime);
            // t是时间戳
            datas.put("t", String.valueOf(DateUtil.pare(starttime) + 10000 + new Random().nextInt(999)));
            //rn 随机数 html 页面有个全局变量 就是这个
            datas.put("rn", rndnum);
            // jqnonce 这个html 中js全局变量也有 应该是服务器传回来的值 还有那个随机数 可以爬虫获取
            datas.put("jqnonce", jqnonce);

            // 这两个参数需要经过计算才能给出
            datas.put("jqpram", getJqpram(rndnum, starttime, Integer.valueOf(curId)));
            datas.put("jqsign", dataenc(jqnonce, ktimes));

            System.out.println(datas.toString());
            url = "https://www.wjx.cn/joinnew/processjq.ashx" + buildMap(datas);
            System.out.println(datas.size());
            url="https://www.wjx.cn/joinnew/processjq.ashx?curID=11891579&submittype=1&t="+(DateUtil.pare(starttime) + 1000 + new Random().nextInt(999))+"&starttime="+URLEncoder.encode(starttime,"UTF-8")+"" +
                    "&ktimes="+ktimes+"&rn="+rndnum+"&jqpram="+getJqpram(rndnum, starttime, Integer.valueOf(curId))+"&hlv=1&jqnonce="+jqnonce+"&jqsign="+URLEncoder.encode(dataenc(jqnonce, ktimes),"UTF-8")+"&jpm=19&isMtitle=0";
            System.out.println(url);
//            Map<String, String> data_map = new HashMap<>();
//            data_map.put("submitdata", data);
//            System.out.println(JSON.toJSONString(data_map));

            Connection.Response response = Jsoup.connect(url)
                    .header("Accept", "*/*")
                    .header("Accept-Encoding", "gzip, deflate, br")
                    .header("Origin ","https://www.wjx.cn")
                    .header("sec-ch-ua","\"Chromium\";v=\"94\", \"Google Chrome\";v=\"94\", \";Not A Brand\";v=\"99\"")
                    .header(USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36")
//                    .header("Content-Type", "text/plain;charset=utf-8")
                    .header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
//                    .requestBody(JSON.toJSONString(data_map))
//                    .data(datas)
                    .data("submitdata",URLEncoder.encode(data, "UTF-8"))
                    .ignoreContentType(true)
                    .followRedirects(true)
                    .method(Connection.Method.POST)
//                    .requestBody("submitdata="+URLEncoder.encode(data, "UTF-8"))
                    .cookies(res.cookies())
                    .execute();

            System.out.println(URLEncoder.encode(data, "UTF-8"));

            System.out.println(response.body());
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        // 配置模拟浏览器
        return true;
    }

    public static Connection.Response login(String userName, String password, String token) {
        Connection con = Jsoup.connect("https://tyutgs.wjx.cn/user/loginForm.aspx?user_token=" + token);
        con.header(USER_AGENT, USER_AGENT_VALUE)
                .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
                .header("Accept-Encoding", "gzip, deflate, sdch")
                .header("Content-Type", "text/html; charset=utf-8");

        try {
            Connection.Response res = con.ignoreContentType(true).
                    followRedirects(true).
                    method(Connection.Method.GET).
                    execute();

            Document document = res.parse();


            Map<String, String> datas = new HashMap<>();
            datas.put("__EVENTTARGET", "btnSubmit");
            datas.put("__EVENTARGUMENT", "");
            datas.put("__VIEWSTATE", document.getElementById("__VIEWSTATE").val());
            // 例子 EA405E62
            datas.put("__VIEWSTATEGENERATOR", document.getElementById("__VIEWSTATEGENERATOR").val());
            datas.put("__EVENTVALIDATION", document.getElementById("__EVENTVALIDATION").val());
            datas.put("hideIsPhone", "");
            datas.put("hfQueryCond", "");
            datas.put("hfQuery", "10000|" + userName + "〒30000|" + password);
            datas.put("hfPwd", document.getElementById("hfPwd").val());
            datas.put("phoneVal", "");
            datas.put("txtVerifyCode_1", "");
            datas.put("checkCode", "");
            datas.put("hidPhone", "");
            datas.put("password", "");
            datas.put("name", "");
            System.out.println(datas);
            Connection connection = Jsoup.connect("https://tyutgs.wjx.cn/user/loginForm.aspx?user_token=" + token)
                    .header(USER_AGENT, USER_AGENT_VALUE)
                    .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
                    .header("Accept-Encoding", "gzip, deflate, sdch")
                    .header("Content-Type", "application/x-www-form-urlencoded");

            Connection.Response response = connection.ignoreContentType(true).
                    followRedirects(true).
                    method(Connection.Method.POST).
                    cookies(res.cookies()).
                    data(datas).
                    execute();
            Document dai = response.parse();

            String uRL = "https://tyutgs.wjx.cn" + dai.select(".surveyItem a").get(0).attr("href");
            System.out.println(uRL);
            Map<String, String> map = UrlUtil.urlSplit(uRL);
            System.out.println(map);
            Map<String, String> data = new HashMap<>();
            data.put("relts", map.get("relts"));
            data.put("relusername", map.get("relusername"));
            data.put("relsign", map.get("relsign"));
            data.put("relrealname", map.get("relrealname"));
            data.put("reldept", map.get("reldept"));
            data.put("relext", map.get("relext"));
            data.put("hmt", "1");
            data.put("vpsiu", "1");
            data.put("sd", "https://tyutgs.wjx.cn");


            return response;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static boolean ty(String url, String data, Map<String, String> datas) {
        try {

            Connection con = Jsoup.connect(url);
            String curId = getCurId(url);
            System.out.println(curId);

            con.header(USER_AGENT, USER_AGENT_VALUE)
                    .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
                    .header("Accept-Encoding", "gzip, deflate, sdch")
                    .header("Content-Type", "text/html; charset=utf-8");

            Connection.Response res = con.ignoreContentType(true).
                    followRedirects(true).
                    method(Connection.Method.GET).
                    execute();

            String temp = res.body();

            datas.put("shortid", curId);
            datas.put("mst", curId);
            datas.put("submittype", "1");

            datas.put("hlv", "1");
//            Integer[2] tt =[321, 176];

            Integer ktimes = 321;
            datas.put("ktimes", String.valueOf(ktimes));

            String rndnum = temp.split("rndnum=\"")[1].split("var simple")[0].replaceAll("\";", "").trim();
            System.out.println("rndnum--" + rndnum);
            String starttime = temp.split("starttime=\"")[1].split("langVer=")[0].replaceAll("\";", "").trim();
            System.out.println("starttime--" + starttime);
            String jqnonce = temp.split("jqnonce=\"")[1].split("var isChuangGuan")[0].replaceAll("\";", "").trim();
            System.out.println("jqnoce--" + jqnonce);
//            String activityId = temp.split("var activityId =")[1].split("activityId=")[0].replaceAll(";", "").trim();

            // t是时间戳
            datas.put("t", String.valueOf(System.currentTimeMillis()));
            //根据时间戳，生成的时间
            datas.put("starttime", starttime);
            //rn 随机数 html 页面有个全局变量 就是这个
            datas.put("rn", rndnum);
            // jqnonce 这个html 中js全局变量也有 应该是服务器传回来的值 还有那个随机数 可以爬虫获取
            datas.put("jqnonce", jqnonce);

            // 这两个参数需要经过计算才能给出
            datas.put("jqpram", getJqpram(rndnum, starttime, Integer.valueOf(curId)));
            datas.put("jqsign", dataenc(jqnonce, ktimes));

            System.out.println(datas.toString());
            url = "https://www.wjx.cn/joinnew/processjq.ashx" + buildMap(datas);
            System.out.println(url);

//            Map<String, String> data_map = new HashMap<>();
//            data_map.put("submitdata", data);
//            System.out.println(JSON.toJSONString(data_map));

            Connection.Response response = Jsoup.connect(url)
                    .header(USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36")
                    .header("Content-Type", "application/x-www-form-urlencoded")
//                    .requestBody(JSON.toJSONString(data_map))
                    .data("submitdata", data)
                    .ignoreContentType(true)
                    .followRedirects(true)
                    .method(Connection.Method.POST)
                    .cookies(res.cookies())
                    .execute();

            System.out.println(response.body());
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        // 配置模拟浏览器
        return true;
    }
}
